Extract shared test types to common module#144
Conversation
Move 14 duplicated type definitions (Container, Config, Checkpoint, BlockHeader, Validator, TestState, Block, BlockBody, AggregatedAttestation, AggregationBits, AttestationData, ProposerAttestation, TestInfo, deser_pubkey_hex) from types.rs and signature_types.rs into a shared common.rs module. This eliminates the maintenance burden and risk of divergence between fork choice and signature tests. Also add autotests = false to Cargo.toml to prevent the helper modules from being auto-discovered as standalone test binaries.
🤖 Kimi Code ReviewReview SummaryThis PR performs a significant refactoring by extracting common test types into a shared module ( Issues Found
Positive Aspects
Recommendations
Automated review by Kimi (Moonshot AI) · custom prompt |
🤖 Codex Code ReviewFindings
Notes
Residual risks / test gaps
If you want, I can propose the minimal Automated review by OpenAI Codex · custom prompt |
Greptile SummarySuccessfully extracted 14 duplicated test type definitions from Key Changes:
Minor Normalization: No logical changes to test behavior. All existing tests should continue to pass. Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| crates/blockchain/Cargo.toml | Added autotests = false to prevent test module files from being auto-discovered as standalone test binaries |
| crates/blockchain/tests/common.rs | New shared types module with 14 extracted types and From implementations, marked with #![allow(dead_code)] |
| crates/blockchain/tests/types.rs | Removed 282 lines of duplicated types, now imports shared types from super::common, only retains fork-choice-specific types |
| crates/blockchain/tests/signature_types.rs | Removed ~280 lines of duplicated types, now imports shared types from super::common, only retains signature-specific types |
Last reviewed commit: 806831e
🤖 Claude Code ReviewNow I have a complete picture of the PR. Let me write the review. PR Review: Extract shared test types to common moduleSummary: Clean refactoring with no logic changes. The 245-line reduction is accurate, and the module boundary design is correct. A few items worth noting:
|
Resolve conflicts: - fork_choice/src/lib.rs: keep extracted compute_block_weights() and adopt safe .get() with early return from PR #137 - blockchain/src/store.rs: keep Store::extract_latest_attestations() dedup - signature_types.rs: take devnet-3's version (imports from common module per PR #144), remove duplicate deser_xmss_hex
`crates/blockchain/tests/types.rs` (fork choice tests) and `crates/blockchain/tests/signature_types.rs` (signature tests) duplicate ~14 type definitions with identical fields, serde attributes, and `From` trait implementations. This creates maintenance burden and risks divergence — any change to shared types (e.g. adding a new field to `TestState` or `Block`) must be applied in two places. Extract the 14 shared types into a new `common.rs` module that both test files import from: | Type | Purpose | |------|---------| | `Container<T>` | Generic serde wrapper for JSON arrays with `data` field | | `Config` + `From<Config> for ChainConfig` | Genesis time config | | `Checkpoint` + `From<Checkpoint> for DomainCheckpoint` | Root + slot pair | | `BlockHeader` + `From<BlockHeader> for block::BlockHeader` | Block header fields | | `Validator` + `From<Validator> for DomainValidator` | Validator index + pubkey | | `TestState` + `From<TestState> for State` | Full beacon state deserialization | | `Block` + `From<Block> for DomainBlock` | Block with body | | `BlockBody` + `From<BlockBody> for DomainBlockBody` | Attestation container | | `AggregatedAttestation` + `From` impl | Aggregation bits + data | | `AggregationBits` + `From` impl | Boolean bitfield | | `AttestationData` + `From` impl | Slot + head/target/source checkpoints | | `ProposerAttestation` + `From` impl | Validator ID + attestation data | | `TestInfo` | Test metadata (hash, comment, description) | | `deser_pubkey_hex()` | Hex string → `ValidatorPubkeyBytes` deserializer | **Files changed:** - **`tests/common.rs`** (new) — shared types with `#![allow(dead_code)]` at module level - **`tests/types.rs`** — reduced to fork-choice-specific types only (`ForkChoiceTestVector`, `ForkChoiceTest`, `ForkChoiceStep`, `BlockStepData`, `StoreChecks`, `AttestationCheck`), imports shared types via `super::common` - **`tests/signature_types.rs`** — reduced to signature-specific types only (SSZ types, `VerifySignaturesTestVector`, `TestSignedBlockWithAttestation`, `ProposerSignature`, etc.), imports shared types via `super::common` - **`tests/forkchoice_spectests.rs`** / **`tests/signature_spectests.rs`** — added `mod common;` - **`Cargo.toml`** — added `autotests = false` to prevent `common.rs`, `types.rs`, and `signature_types.rs` from being auto-discovered as standalone test binaries **Net result:** -575 lines added, +330 lines removed = **245 fewer lines** of duplicated code. The `From<BlockBody>` impl differed slightly between files: - `types.rs`: `VariableList::new(attestations).expect(...)` - `signature_types.rs`: `collect::<Vec<_>>().try_into().expect(...)` Both are equivalent. The common module uses the `VariableList::new()` form. ```bash make fmt # No formatting changes make lint # No warnings make test # All 26 forkchoice spec tests pass ``` Note: `signature_spectests` have pre-existing failures (fixture format mismatch with `ProposerSignature` — the JSON provides a hex string where the code expects a struct). These failures are identical on `main` and are unrelated to this change.
`crates/blockchain/tests/types.rs` (fork choice tests) and `crates/blockchain/tests/signature_types.rs` (signature tests) duplicate ~14 type definitions with identical fields, serde attributes, and `From` trait implementations. This creates maintenance burden and risks divergence — any change to shared types (e.g. adding a new field to `TestState` or `Block`) must be applied in two places. Extract the 14 shared types into a new `common.rs` module that both test files import from: | Type | Purpose | |------|---------| | `Container<T>` | Generic serde wrapper for JSON arrays with `data` field | | `Config` + `From<Config> for ChainConfig` | Genesis time config | | `Checkpoint` + `From<Checkpoint> for DomainCheckpoint` | Root + slot pair | | `BlockHeader` + `From<BlockHeader> for block::BlockHeader` | Block header fields | | `Validator` + `From<Validator> for DomainValidator` | Validator index + pubkey | | `TestState` + `From<TestState> for State` | Full beacon state deserialization | | `Block` + `From<Block> for DomainBlock` | Block with body | | `BlockBody` + `From<BlockBody> for DomainBlockBody` | Attestation container | | `AggregatedAttestation` + `From` impl | Aggregation bits + data | | `AggregationBits` + `From` impl | Boolean bitfield | | `AttestationData` + `From` impl | Slot + head/target/source checkpoints | | `ProposerAttestation` + `From` impl | Validator ID + attestation data | | `TestInfo` | Test metadata (hash, comment, description) | | `deser_pubkey_hex()` | Hex string → `ValidatorPubkeyBytes` deserializer | **Files changed:** - **`tests/common.rs`** (new) — shared types with `#![allow(dead_code)]` at module level - **`tests/types.rs`** — reduced to fork-choice-specific types only (`ForkChoiceTestVector`, `ForkChoiceTest`, `ForkChoiceStep`, `BlockStepData`, `StoreChecks`, `AttestationCheck`), imports shared types via `super::common` - **`tests/signature_types.rs`** — reduced to signature-specific types only (SSZ types, `VerifySignaturesTestVector`, `TestSignedBlockWithAttestation`, `ProposerSignature`, etc.), imports shared types via `super::common` - **`tests/forkchoice_spectests.rs`** / **`tests/signature_spectests.rs`** — added `mod common;` - **`Cargo.toml`** — added `autotests = false` to prevent `common.rs`, `types.rs`, and `signature_types.rs` from being auto-discovered as standalone test binaries **Net result:** -575 lines added, +330 lines removed = **245 fewer lines** of duplicated code. The `From<BlockBody>` impl differed slightly between files: - `types.rs`: `VariableList::new(attestations).expect(...)` - `signature_types.rs`: `collect::<Vec<_>>().try_into().expect(...)` Both are equivalent. The common module uses the `VariableList::new()` form. ```bash make fmt # No formatting changes make lint # No warnings make test # All 26 forkchoice spec tests pass ``` Note: `signature_spectests` have pre-existing failures (fixture format mismatch with `ProposerSignature` — the JSON provides a hex string where the code expects a struct). These failures are identical on `main` and are unrelated to this change.
Motivation
crates/blockchain/tests/types.rs(fork choice tests) andcrates/blockchain/tests/signature_types.rs(signature tests) duplicate ~14 type definitions with identical fields, serde attributes, andFromtrait implementations. This creates maintenance burden and risks divergence — any change to shared types (e.g. adding a new field toTestStateorBlock) must be applied in two places.Description
Extract the 14 shared types into a new
common.rsmodule that both test files import from:Container<T>datafieldConfig+From<Config> for ChainConfigCheckpoint+From<Checkpoint> for DomainCheckpointBlockHeader+From<BlockHeader> for block::BlockHeaderValidator+From<Validator> for DomainValidatorTestState+From<TestState> for StateBlock+From<Block> for DomainBlockBlockBody+From<BlockBody> for DomainBlockBodyAggregatedAttestation+FromimplAggregationBits+FromimplAttestationData+FromimplProposerAttestation+FromimplTestInfodeser_pubkey_hex()ValidatorPubkeyBytesdeserializerFiles changed:
tests/common.rs(new) — shared types with#![allow(dead_code)]at module leveltests/types.rs— reduced to fork-choice-specific types only (ForkChoiceTestVector,ForkChoiceTest,ForkChoiceStep,BlockStepData,StoreChecks,AttestationCheck), imports shared types viasuper::commontests/signature_types.rs— reduced to signature-specific types only (SSZ types,VerifySignaturesTestVector,TestSignedBlockWithAttestation,ProposerSignature, etc.), imports shared types viasuper::commontests/forkchoice_spectests.rs/tests/signature_spectests.rs— addedmod common;Cargo.toml— addedautotests = falseto preventcommon.rs,types.rs, andsignature_types.rsfrom being auto-discovered as standalone test binariesNet result: -575 lines added, +330 lines removed = 245 fewer lines of duplicated code.
Minor normalization
The
From<BlockBody>impl differed slightly between files:types.rs:VariableList::new(attestations).expect(...)signature_types.rs:collect::<Vec<_>>().try_into().expect(...)Both are equivalent. The common module uses the
VariableList::new()form.How to Test
Note:
signature_spectestshave pre-existing failures (fixture format mismatch withProposerSignature— the JSON provides a hex string where the code expects a struct). These failures are identical onmainand are unrelated to this change.